﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Xml.Serialization;
namespace DwarfFortClone
{
    public class XNA2dCamera
    {
        #region Properties and Fields
        #region Position
        Game theGame;
        Vector2 screensize;

        protected Vector2 position = Vector2.Zero;
        public Vector2 Position
        {
            get { return position; }
            set
            {
                position = value;


                int left = (int)(position.X + offset.X - visibleArea.Width / 2);
                int top = (int)(position.Y + offset.Y - visibleArea.Height / 2);
                visibleArea.Width = visibleArea.Width + left - visibleArea.X;
                visibleArea.Height = visibleArea.Height + top - visibleArea.Y;
                visibleArea.X = left;
                visibleArea.Y = left;


            }
        }

        protected Vector2 offset = Vector2.Zero;
        public Vector2 Offset
        {
            get { return offset; }
            set
            {
                offset = value;
                int left = (int)(position.X + offset.X - visibleArea.Width / 2);
                int top = (int)(position.Y + offset.Y - visibleArea.Height / 2);
                visibleArea.Width = visibleArea.Width + left - visibleArea.X;
                visibleArea.Height = visibleArea.Height + top - visibleArea.Y;
                visibleArea.X = left;
                visibleArea.Y = left;


            }
        }
        #endregion Position

        #region Culling
        // RectangleF = a Rectangle class that uses floats instead of ints
        protected Rectangle visibleArea;
        public Rectangle VisibleArea
        {
            get { return visibleArea; }
        }

        public float ViewingWidth
        {
            get { return visibleArea.Width; }
            set { visibleArea.Width = (int)value; }
        }

        public float ViewingHeight
        {
            get { return visibleArea.Height; }
            set { visibleArea.Height = (int)value; }
        }

        //Get the bounding rectangle of the viewable
        //screen
        public Vector2 screenSize()
        {
            Vector2 screenSize = screensize;
            return Vector2.Transform(screenSize, Matrix.CreateScale(1 / Zoom.X, 1 / Zoom.Y, 1.0f));
        }
        #endregion Culling

        #region Transformations
        protected float rotation = 0.0f;
        public float Rotation
        {
            get { return rotation; }
            set { rotation = value; }
        }

        // <0 - <1 = Zoom Out
        // >1 = Zoom In
        // <0 = Funky (flips axis)
        protected Vector2 zoom = Vector2.One;
        public Vector2 Zoom
        {
            get { return zoom; }
            set { zoom = value; }
        }
        #endregion Transformations

        public Vector2 ScreenPosition
        {
            get { return new Vector2(theGame.GraphicsDevice.Viewport.Width / 2, theGame.GraphicsDevice.Viewport.Height / 2); }
        }
        #endregion Properties and Fields

        #region Constructors
        public XNA2dCamera(DwarfGame g)
        {
            theGame = g;
            visibleArea = new Rectangle(0, 0, theGame.GraphicsDevice.Viewport.Width, theGame.GraphicsDevice.Viewport.Height);
            position = ScreenPosition;
            screensize = new Vector2(g.configuration.screenWidth, g.configuration.screenHeight);

        }
        public XNA2dCamera(float width, float height, DwarfGame g)
        {
            screensize = new Vector2(g.configuration.screenWidth, g.configuration.screenHeight);
            visibleArea = new Rectangle(0, 0, (int)width, (int)height);
            position = ScreenPosition;
            theGame = g;
        }
        public XNA2dCamera(float x, float y, float width, float height, DwarfGame g)
        {
            visibleArea = new Rectangle((int)(x - (width / 2)), (int)(y - (height / 2)), (int)(width), (int)height);
            position.X = x;
            position.Y = y;
            theGame = g;
            screensize = new Vector2(g.configuration.screenWidth, g.configuration.screenHeight);
        }
        #endregion Constructors

        #region Destructors
        public void Dispose()
        {



        }
        #endregion

        #region Methods
        ///
        /// Returns a transformation matrix based on the camera’s position, rotation, and zoom.
        /// Best used as a parameter for the SpriteBatch.Begin() call.
        ///
        public virtual Matrix ViewTransformationMatrix()
        {
            Vector3 matrixRotOrigin = new Vector3(Position + Offset, 0);
            Vector3 matrixScreenPos = new Vector3(ScreenPosition, 0.0f);

            // Translate back to the origin based on the camera’s offset position, since we’re rotating around the camera
            // Then, we scale and rotate around the origin
            // Finally, we translate to SCREEN coordinates, so translation is based on the ScreenCenter
            return Matrix.CreateTranslation(-matrixRotOrigin) *
                Matrix.CreateScale(Zoom.X, Zoom.Y, 1.0f) *
                Matrix.CreateRotationZ(Rotation) *
                Matrix.CreateTranslation(matrixScreenPos);
        }
        #endregion Methods
    }
}